﻿
/*******************************************************************************************
// ©2009 Microsoft Corporation.  This code is provided under the Microsoft Public License.
*******************************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Activation;
using System.Configuration;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace UCMACellularWS
{
    /// <summary>
    /// Factory class which retuns new ServiceHost object
    /// </summary>
    public class CustomServiceHostFactory : ServiceHostFactoryBase
    {
        public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
        {
            return new CustomServiceHost(baseAddresses);
        }
    }

    /// <summary>
    /// This is a custom service host which overrides base methods for configuration and cleanup purposes
    /// </summary>
    class CustomServiceHost : ServiceHost
    {
        private PubSubLogger logger = new PubSubLogger();
       
        protected override void OnOpened()
        {
            base.OnOpened();
            logger.Log("Started", System.Diagnostics.EventLogEntryType.Information);

            //Initialize resources
            PubSub.Logger = logger;
            

            //Get Configuration settings
            string configXMLDoc = "";
            string physicalPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
            using (TextReader reader = new StreamReader(System.IO.Path.Combine (physicalPath,"Config.xml")))
            {
                configXMLDoc = reader.ReadToEnd();
            }

            //Parse the config xml doc into an Xdocument
            XDocument configDoc;
            configDoc = XDocument.Parse(configXMLDoc);

            PubSub.Config.TargetUsers = (from User in configDoc.Element("users").Descendants("targetUser")
                                        select new TargetUserConfiguration
                                        {
                                            Uri = User.Element("uri").Value,
                                            SMSAddress = User.Element("smsAddress").Value
                                        }).ToList();
                       


            //Setup Collaboration platform for the bot
            //It sets up Bot End point
            PlatformManager.PreparePlatformAndEndpoint();

            //Sets up Endpoints for every target users and subscribe to their own presence.
            //It also registers handlers to intercept IM calls for all the target users.
            PubSub.SubscribeToPresence();
        }

        protected override void OnClosing()
        {
            base.OnClosing();

            //Cleanup Resources
            PubSub.Cleanup();

            logger.Log("Cleanup completed.", System.Diagnostics.EventLogEntryType.Information);
        }

        public CustomServiceHost(params Uri[] addresses)
            : base(typeof(PubSub), addresses)
        {
        }

        //Overriding ApplyConfiguration() allows us to 
        //alter the ServiceDescription prior to opening
        //the service host. 
        protected override void ApplyConfiguration()
        {
            //First, we call base.ApplyConfiguration()
            //to read any configuration that was provided for
            //the service we're hosting. After this call,
            //this.ServiceDescription describes the service
            //as it was configured.
            base.ApplyConfiguration();

            //Now that we've populated the ServiceDescription, we can reach into it
            //and do interesting things (in this case, we'll add an instance of
            //ServiceMetadataBehavior if it's not already there.
            ServiceMetadataBehavior mexBehavior = this.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (mexBehavior == null)
            {
                mexBehavior = new ServiceMetadataBehavior();
                this.Description.Behaviors.Add(mexBehavior);
            }
            else
            {
                //Metadata behavior has already been configured, 
                //so we don't have any work to do.
                return;
            }

            //Add a metadata endpoint at each base address
            //using the "/mex" addressing convention
            foreach (Uri baseAddress in this.BaseAddresses)
            {
                if (baseAddress.Scheme == Uri.UriSchemeHttp)
                {
                    mexBehavior.HttpGetEnabled = true;
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexHttpBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeHttps)
                {
                    mexBehavior.HttpsGetEnabled = true;
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexHttpsBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
                {
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexNamedPipeBinding(),
                                            "mex");
                }
                else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
                {
                    this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                            MetadataExchangeBindings.CreateMexTcpBinding(),
                                            "mex");
                }
            }

        }
    }

}
